home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16_Src.lha / Python16_Source / Modules / pyexpat.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-03  |  25.2 KB  |  840 lines

  1. #include "Python.h"
  2. #include "xmlparse.h"
  3.  
  4. /*
  5. ** The version number should match the one in _checkversion
  6. */
  7. #define VERSION "1.9"
  8.  
  9. enum HandlerTypes{
  10.         StartElement, 
  11.         EndElement, 
  12.         ProcessingInstruction, 
  13.         CharacterData,
  14.         UnparsedEntityDecl,
  15.         NotationDecl,
  16.         StartNamespaceDecl,
  17.         EndNamespaceDecl,
  18.         Comment,
  19.         StartCdataSection,
  20.         EndCdataSection,
  21.         Default,
  22.         DefaultHandlerExpand,
  23.         NotStandalone,
  24.         ExternalEntityRef
  25. };
  26.  
  27. static PyObject *ErrorObject;
  28.  
  29. /* ----------------------------------------------------- */
  30.  
  31. /* Declarations for objects of type xmlparser */
  32.  
  33. typedef struct {
  34.         PyObject_HEAD
  35.  
  36.         XML_Parser itself;
  37.         PyObject **handlers;
  38. } xmlparseobject;
  39.  
  40. staticforward PyTypeObject Xmlparsetype;
  41.  
  42. typedef void (*xmlhandlersetter)( XML_Parser *self, void *meth );
  43. typedef void* xmlhandler;
  44.  
  45. struct HandlerInfo{
  46.         const char *name;
  47.         xmlhandlersetter setter;
  48.         xmlhandler handler;
  49. };
  50.  
  51. staticforward struct HandlerInfo handler_info[];
  52.  
  53. static PyObject *conv_atts( XML_Char **atts){
  54.         PyObject *attrs_obj=NULL;
  55.         XML_Char **attrs_p, **attrs_k;
  56.         int attrs_len;
  57.         PyObject *rv;
  58.  
  59.         if( (attrs_obj = PyDict_New()) == NULL ) 
  60.                 goto finally;
  61.         for(attrs_len=0, attrs_p = atts; 
  62.             *attrs_p;
  63.             attrs_p++, attrs_len++) {
  64.                 if (attrs_len%2) {
  65.                         rv=PyString_FromString(*attrs_p);  
  66.                         if (! rv) {
  67.                                 Py_DECREF(attrs_obj);
  68.                                 attrs_obj=NULL;
  69.                                 goto finally;
  70.                         }
  71.                         if (PyDict_SetItemString(
  72.                                attrs_obj,
  73.                                (char*)*attrs_k, rv) < 0){
  74.                                 Py_DECREF(attrs_obj);
  75.                                 attrs_obj=NULL;
  76.                                 goto finally;
  77.                         }
  78.                         Py_DECREF(rv);
  79.                 }
  80.                 else attrs_k=attrs_p;
  81.         }
  82.         finally:
  83.         return attrs_obj;
  84. }
  85.  
  86. /* Callback routines */
  87.  
  88. void clear_handlers( xmlparseobject *self );
  89.  
  90. void flag_error( xmlparseobject *self ){
  91.         clear_handlers(self);
  92. }
  93.  
  94. #define RC_HANDLER( RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
  95.                 RETURN, GETUSERDATA) \
  96. \
  97. static RC my_##NAME##Handler PARAMS {\
  98.         xmlparseobject *self = GETUSERDATA ; \
  99.         PyObject *args=NULL; \
  100.         PyObject *rv=NULL; \
  101.         INIT \
  102. \
  103.         if (self->handlers[NAME] \
  104.             && self->handlers[NAME] != Py_None) { \
  105.                 args = Py_BuildValue PARAM_FORMAT ;\
  106.                 if (!args) return RETURN; \
  107.                 rv = PyEval_CallObject(self->handlers[NAME], args); \
  108.                 Py_DECREF(args); \
  109.                 if (rv == NULL) { \
  110.                         flag_error( self ); \
  111.                         return RETURN; \
  112.                 } \
  113.                 CONVERSION \
  114.                 Py_DECREF(rv); \
  115.         } \
  116.         return RETURN; \
  117. }
  118.  
  119. #define NOTHING /**/
  120.  
  121. #define VOID_HANDLER( NAME, PARAMS, PARAM_FORMAT ) \
  122.         RC_HANDLER( void, NAME, PARAMS, NOTHING, PARAM_FORMAT, NOTHING, NOTHING,\
  123.         (xmlparseobject *)userData )
  124.  
  125. #define INT_HANDLER( NAME, PARAMS, PARAM_FORMAT )\
  126.         RC_HANDLER( int, NAME, PARAMS, int rc=0;, PARAM_FORMAT,  \
  127.                         rc = PyInt_AsLong( rv );, rc, \
  128.         (xmlparseobject *)userData )
  129.  
  130. VOID_HANDLER( StartElement, 
  131.                 (void *userData, const XML_Char *name, const XML_Char **atts ), 
  132.                 ("(sO&)", name, conv_atts, atts ) )
  133.  
  134. VOID_HANDLER( EndElement, 
  135.                 (void *userData, const XML_Char *name ), 
  136.                 ("(s)", name) )
  137.  
  138. VOID_HANDLER( ProcessingInstruction,
  139.                 (void *userData, 
  140.                 const XML_Char *target, 
  141.                 const XML_Char *data),
  142.                 ("(ss)",target, data ))
  143.  
  144. VOID_HANDLER( CharacterData, 
  145.                 (void *userData, const XML_Char *data, int len), 
  146.                 ("(s#)", data, len ) )
  147.  
  148. VOID_HANDLER( UnparsedEntityDecl,
  149.                 (void *userData, 
  150.                         const XML_Char *entityName,
  151.                         const XML_Char *base,
  152.                         const XML_Char *systemId,
  153.                         const XML_Char *publicId,
  154.                         const XML_Char *notationName),
  155.                 ("(sssss)", entityName, base, systemId, publicId, notationName))
  156.  
  157. VOID_HANDLER( NotationDecl, 
  158.                 (void *userData,
  159.                         const XML_Char *notationName,
  160.                         const XML_Char *base,
  161.                         const XML_Char *systemId,
  162.                         const XML_Char *publicId),
  163.                 ("(ssss)", notationName, base, systemId, publicId))
  164.  
  165. VOID_HANDLER( StartNamespaceDecl,
  166.                 (void *userData,
  167.                       const XML_Char *prefix,
  168.                       const XML_Char *uri),
  169.                 ("(ss)", prefix, uri ))
  170.  
  171. VOID_HANDLER( EndNamespaceDecl,
  172.                 (void *userData,
  173.                     const XML_Char *prefix),
  174.                 ("(s)", prefix ))
  175.  
  176. VOID_HANDLER( Comment,
  177.                (void *userData, const XML_Char *prefix),
  178.                 ("(s)", prefix))
  179.  
  180. VOID_HANDLER( StartCdataSection,
  181.                (void *userData),
  182.               ("()" ))
  183.                 
  184. VOID_HANDLER( EndCdataSection,
  185.                (void *userData),
  186.                 ("()" ))
  187.  
  188. VOID_HANDLER( Default,
  189.                 (void *userData,  const XML_Char *s, int len),
  190.                 ("(s#)",s,len))
  191.  
  192. VOID_HANDLER( DefaultHandlerExpand,
  193.                 (void *userData,  const XML_Char *s, int len),
  194.                 ("(s#)",s,len))
  195.  
  196. INT_HANDLER( NotStandalone, 
  197.                 (void *userData), 
  198.                 ("()"))
  199.  
  200. RC_HANDLER( int, ExternalEntityRef,
  201.                 (XML_Parser parser,
  202.                     const XML_Char *context,
  203.                     const XML_Char *base,
  204.                     const XML_Char *systemId,
  205.                     const XML_Char *publicId),
  206.                 int rc=0;,
  207.                 ("(ssss)", context, base, systemId, publicId ),
  208.                 rc = PyInt_AsLong( rv );, rc,
  209.                 XML_GetUserData( parser ) )
  210.                 
  211.  
  212.  
  213. /* File reading copied from cPickle */
  214.  
  215. #define UNLESS(E) if (!(E))
  216.  
  217. /*
  218. static int 
  219. read_other(xmlparseobject *self, char **s, int  n) {
  220.     PyObject *bytes=NULL, *str=NULL, *arg=NULL;
  221.     int res = -1;
  222.  
  223.     UNLESS(bytes = PyInt_FromLong(n)) {
  224.         if (!PyErr_Occurred())
  225.             PyErr_SetNone(PyExc_EOFError);
  226.  
  227.         goto finally;
  228.     }
  229.  
  230.     UNLESS(arg)
  231.         UNLESS(arg = PyTuple_New(1))
  232.             goto finally;
  233.  
  234.     Py_INCREF(bytes);
  235.     if (PyTuple_SetItem(arg, 0, bytes) < 0)
  236.         goto finally;
  237.  
  238.     UNLESS(str = PyObject_CallObject(self->read, arg))
  239.         goto finally;
  240.  
  241.     *s = PyString_AsString(str);
  242.  
  243.     res = n;
  244.  
  245. finally:
  246.      Py_XDECREF(arg);
  247.      Py_XDECREF(bytes);
  248.  
  249.      return res;
  250. }
  251.  
  252. */
  253.  
  254.  
  255.     
  256.  
  257.  
  258. /* ---------------------------------------------------------------- */
  259.  
  260. static char xmlparse_Parse__doc__[] = 
  261. "(data [,isfinal]) - Parse XML data"
  262. ;
  263.  
  264. static PyObject *
  265. xmlparse_Parse( xmlparseobject *self, PyObject *args )
  266. {
  267.         char *s;
  268.         int slen;
  269.         int isFinal = 0;
  270.         int rv;
  271.  
  272.         if (!PyArg_ParseTuple(args, "s#|i", &s, &slen, &isFinal))
  273.                 return NULL;
  274.         rv = XML_Parse(self->itself, s, slen, isFinal);
  275.         if( PyErr_Occurred() ){ 
  276.                 return NULL;
  277.         }
  278.         else if (rv == 0) {
  279.                 PyErr_Format(ErrorObject, "%.200s: line %i, column %i",
  280.                              XML_ErrorString( XML_GetErrorCode(self->itself) ),
  281.                              XML_GetErrorLineNumber(self->itself),
  282.                              XML_GetErrorColumnNumber(self->itself) );
  283.                 return NULL;
  284.         }
  285.  
  286.         return Py_BuildValue("i", rv);
  287. }
  288.  
  289. #define BUF_SIZE 2048
  290.  
  291. int readinst(char *buf, int buf_size, PyObject *meth){
  292.         PyObject *arg=NULL;
  293.         PyObject *bytes=NULL;
  294.         PyObject *str=NULL;
  295.         int len;
  296.  
  297.         UNLESS(bytes = PyInt_FromLong(buf_size)) {
  298.                 if (!PyErr_Occurred())
  299.                 PyErr_SetNone(PyExc_EOFError);
  300.                 goto finally;
  301.         }
  302.  
  303.         UNLESS(arg)
  304.                 UNLESS(arg = PyTuple_New(1))
  305.                     goto finally;
  306.  
  307.         Py_INCREF(bytes);
  308.         if (PyTuple_SetItem(arg, 0, bytes) < 0)
  309.                 goto finally;
  310.  
  311.         UNLESS(str = PyObject_CallObject(meth, arg))
  312.                 goto finally;
  313.  
  314.         UNLESS(PyString_Check( str ))
  315.                 goto finally;
  316.  
  317.         len=PyString_GET_SIZE( str );
  318.         strncpy( buf, PyString_AsString(str), len );
  319.         Py_XDECREF( str );
  320. finally:
  321.         return len;
  322. }
  323.  
  324. static char xmlparse_ParseFile__doc__[] = 
  325. "(file) - Parse XML data"
  326. ;
  327.  
  328. static PyObject *
  329. xmlparse_ParseFile( xmlparseobject *self, PyObject *args )
  330. {
  331.         int rv=1;
  332.         PyObject *f;
  333.         FILE *fp;
  334.         PyObject *readmethod=NULL;
  335.  
  336.         if (!PyArg_ParseTuple(args, "O", &f))
  337.                 return NULL;
  338.  
  339.         if (PyFile_Check(f)) {
  340.                 fp = PyFile_AsFile(f);
  341.         }else{
  342.                 fp = NULL;
  343.                 UNLESS(readmethod = PyObject_GetAttrString(f, "read")) {
  344.                     PyErr_Clear();
  345.                     PyErr_SetString( PyExc_TypeError, 
  346.                         "argument must have 'read' attribute" );
  347.                     return 0;
  348.                 }
  349.         }
  350.         
  351.         for (;;) {
  352.                   int bytes_read;
  353.                   void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
  354.                   if (buf == NULL) {
  355.                           /* FIXME: throw exception for no memory */
  356.                           return NULL;
  357.                   }
  358.  
  359.                   if( fp ){
  360.                           bytes_read=fread( buf, sizeof( char ), BUF_SIZE, fp);
  361.                   }else{
  362.                           bytes_read=readinst( buf, BUF_SIZE, readmethod );
  363.                   }
  364.  
  365.                   if (bytes_read < 0) {
  366.                         PyErr_SetFromErrno(PyExc_IOError);
  367.                         return NULL;
  368.                   }
  369.                   rv=XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
  370.                   if( PyErr_Occurred() ){
  371.                         return NULL;
  372.                   }
  373.                   if (!rv || bytes_read == 0)
  374.                         break;
  375.         }
  376.  
  377.         return Py_BuildValue("i", rv);
  378. }
  379.  
  380. static char xmlparse_SetBase__doc__[] = 
  381. "(base_url) - Base URL string"
  382. ;
  383.  
  384. static PyObject *
  385. xmlparse_SetBase( xmlparseobject *self, PyObject *args ){
  386.     char *base;
  387.  
  388.     if (!PyArg_ParseTuple(args, "s", &base))
  389.         return NULL;
  390.     if( !XML_SetBase( self->itself, base ) ){
  391.         PyErr_SetNone(PyExc_MemoryError);
  392.         return NULL;
  393.     }
  394.  
  395.     Py_INCREF(Py_None);
  396.     return Py_None;
  397. }
  398.  
  399. static char xmlparse_GetBase__doc__[] = 
  400. "() - returns base URL string "
  401. ;
  402.  
  403. static PyObject *
  404. xmlparse_GetBase( xmlparseobject *self, PyObject *args ){
  405.     const XML_Char *base;
  406.     PyObject *rc;
  407.  
  408.     if( PyTuple_Size( args )!=0 ){
  409.             PyArg_ParseTuple(args, "()" ); /* get good error reporting */
  410.         return NULL;
  411.     }
  412.     base=XML_GetBase( self->itself );
  413.     if( base ){
  414.         rc=Py_BuildValue("s", base);
  415.     }else{
  416.         Py_INCREF(Py_None);
  417.         rc=Py_None;
  418.     }
  419.     return rc;
  420.  
  421. }
  422.  
  423. static struct PyMethodDef xmlparse_methods[] = {
  424.         {"Parse",       (PyCFunction)xmlparse_Parse,
  425.                 METH_VARARGS,   xmlparse_Parse__doc__},
  426.         {"ParseFile",   (PyCFunction)xmlparse_ParseFile,
  427.                 METH_VARARGS,   xmlparse_ParseFile__doc__},
  428.         {"SetBase", (PyCFunction)xmlparse_SetBase,
  429.                 METH_VARARGS,      xmlparse_SetBase__doc__},
  430.         {"GetBase", (PyCFunction)xmlparse_GetBase,
  431.                 METH_VARARGS,      xmlparse_GetBase__doc__},
  432.         {NULL,          NULL}           /* sentinel */
  433. };
  434.  
  435. /* ---------- */
  436.  
  437.  
  438. static xmlparseobject *
  439. newxmlparseobject( char *encoding, char *namespace_separator){
  440.         int i;
  441.         xmlparseobject *self;
  442.         
  443.         self = PyObject_New(xmlparseobject, &Xmlparsetype);
  444.         if (self == NULL)
  445.                 return NULL;
  446.  
  447.         if (namespace_separator) {
  448.                 self->itself = XML_ParserCreateNS(encoding, 
  449.                                                 *namespace_separator);
  450.         }else{
  451.                 self->itself = XML_ParserCreate(encoding);
  452.         }
  453.  
  454.         if( self->itself==NULL ){
  455.                         PyErr_SetString(PyExc_RuntimeError, 
  456.                                         "XML_ParserCreate failed");
  457.                         Py_DECREF(self);
  458.                         return NULL;
  459.         }
  460.  
  461.         XML_SetUserData(self->itself, (void *)self);
  462.  
  463.         for( i=0; handler_info[i].name!=NULL;i++);
  464.  
  465.         self->handlers=malloc( sizeof( PyObject *)*i );
  466.  
  467.         clear_handlers( self );
  468.  
  469.         return self;
  470. }
  471.  
  472.  
  473. static void
  474. xmlparse_dealloc( xmlparseobject *self )
  475. {
  476.         int i;
  477.         if (self->itself)
  478.                 XML_ParserFree(self->itself);
  479.         self->itself = NULL;
  480.  
  481.         for( i=0; handler_info[i].name!=NULL; i++ ){
  482.                 Py_XDECREF( self->handlers[i] );
  483.         }
  484.         PyObject_Del(self);
  485. }
  486.  
  487. static int handlername2int( const char *name ){
  488.         int i;
  489.         for( i=0;handler_info[i].name!=NULL;i++){
  490.                 if( strcmp( name, handler_info[i].name )==0 ){
  491.                         return i;
  492.                 }
  493.         }
  494.         return -1;
  495. }
  496.  
  497. static PyObject *
  498. xmlparse_getattr(xmlparseobject *self, char *name)
  499. {
  500.         int handlernum;
  501.         if (strcmp(name, "ErrorCode") == 0)
  502.                 return Py_BuildValue("l",
  503.                                 (long)XML_GetErrorCode(self->itself));
  504.         if (strcmp(name, "ErrorLineNumber") == 0)
  505.                 return Py_BuildValue("l",
  506.                                 (long)XML_GetErrorLineNumber(self->itself));
  507.         if (strcmp(name, "ErrorColumnNumber") == 0)
  508.                 return Py_BuildValue("l",
  509.                                 (long)XML_GetErrorColumnNumber(self->itself));
  510.         if (strcmp(name, "ErrorByteIndex") == 0)
  511.                 return Py_BuildValue("l",
  512.                                 XML_GetErrorByteIndex(self->itself));
  513.  
  514.         handlernum=handlername2int( name );
  515.  
  516.         if( handlernum!=-1 && self->handlers[handlernum]!=NULL){
  517.                 Py_INCREF( self->handlers[handlernum] );
  518.                 return self->handlers[handlernum];
  519.         }
  520.  
  521.         if (strcmp(name, "__members__") == 0){
  522.                 int i;
  523.                 PyObject *rc=PyList_New(0);
  524.                 for(i=0; handler_info[i].name!=NULL;i++ ){
  525.                         PyList_Append( rc, 
  526.                                 PyString_FromString( handler_info[i].name ) );
  527.                 }
  528.                 PyList_Append( rc, PyString_FromString( "ErrorCode" )); 
  529.                 PyList_Append( rc, PyString_FromString( "ErrorLineNumber" ));
  530.                 PyList_Append( rc, PyString_FromString( "ErrorColumnNumber")); 
  531.                 PyList_Append( rc, PyString_FromString( "ErrorByteIndex" )); 
  532.  
  533.                 return rc;
  534.         }
  535.  
  536.         return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
  537. }
  538.  
  539. static int sethandler( xmlparseobject *self, const char *name, PyObject* v ){
  540.         int handlernum = handlername2int( name );
  541.         if( handlernum!=-1 ){
  542.                 Py_INCREF( v );
  543.                 Py_XDECREF( self->handlers[handlernum] );
  544.                 self->handlers[handlernum]=v;
  545.                 handler_info[handlernum].setter( self->itself, 
  546.                                 handler_info[handlernum].handler );
  547.                 return 1;
  548.         }
  549.  
  550.         return 0;
  551. }
  552.  
  553. static int
  554. xmlparse_setattr( xmlparseobject *self, char *name, PyObject *v)
  555. {
  556.         /* Set attribute 'name' to value 'v'. v==NULL means delete */
  557.         if (v==NULL) {
  558.                 PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
  559.                 return -1;
  560.         }
  561.  
  562.         if( sethandler( self, name, v ) ){
  563.                 return 0;
  564.         }
  565.  
  566.         PyErr_SetString( PyExc_AttributeError, name );
  567.         return -1;
  568. }
  569.  
  570. static char Xmlparsetype__doc__[] = 
  571. "XML parser"
  572. ;
  573.  
  574. static PyTypeObject Xmlparsetype = {
  575.         PyObject_HEAD_INIT(NULL)
  576.         0,                              /*ob_size*/
  577.         "xmlparser",                    /*tp_name*/
  578.         sizeof(xmlparseobject),         /*tp_basicsize*/
  579.         0,                              /*tp_itemsize*/
  580.         /* methods */
  581.         (destructor)xmlparse_dealloc,   /*tp_dealloc*/
  582.         (printfunc)0,           /*tp_print*/
  583.         (getattrfunc)xmlparse_getattr,  /*tp_getattr*/
  584.         (setattrfunc)xmlparse_setattr,  /*tp_setattr*/
  585.         (cmpfunc)0,             /*tp_compare*/
  586.         (reprfunc)0,            /*tp_repr*/
  587.         0,                      /*tp_as_number*/
  588.         0,              /*tp_as_sequence*/
  589.         0,              /*tp_as_mapping*/
  590.         (hashfunc)0,            /*tp_hash*/
  591.         (ternaryfunc)0,         /*tp_call*/
  592.         (reprfunc)0,            /*tp_str*/
  593.  
  594.         /* Space for future expansion */
  595.         0L,0L,0L,0L,
  596.         Xmlparsetype__doc__ /* Documentation string */
  597. };
  598.  
  599. /* End of code for xmlparser objects */
  600. /* -------------------------------------------------------- */
  601.  
  602.  
  603. static char pyexpat_ParserCreate__doc__[] =
  604. "([encoding, namespace_separator]) - Return a new XML parser object"
  605. ;
  606.  
  607. static PyObject *
  608. pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw) {
  609.         char *encoding  = NULL, *namespace_separator=NULL;
  610.         static char *kwlist[] = {"encoding", "namespace_separator", NULL};
  611.  
  612.         if (!PyArg_ParseTupleAndKeywords(args, kw, "|zz", kwlist,
  613.                                          &encoding, &namespace_separator))
  614.                 return NULL;
  615.         return (PyObject *)newxmlparseobject(encoding, namespace_separator);
  616. }
  617.  
  618. static char pyexpat_ErrorString__doc__[] =
  619. "(errno) Returns string error for given number"
  620. ;
  621.  
  622. static PyObject *
  623. pyexpat_ErrorString(self, args)
  624.         PyObject *self; /* Not used */
  625.         PyObject *args;
  626. {
  627.         long code;
  628.         
  629.         if (!PyArg_ParseTuple(args, "l", &code))
  630.                 return NULL;
  631.         return Py_BuildValue("z", XML_ErrorString((int)code));
  632. }
  633.  
  634. /* List of methods defined in the module */
  635.  
  636. static struct PyMethodDef pyexpat_methods[] = {
  637.         {"ParserCreate",        (PyCFunction)pyexpat_ParserCreate,
  638.                  METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
  639.         {"ErrorString", (PyCFunction)pyexpat_ErrorString,
  640.                 METH_VARARGS,   pyexpat_ErrorString__doc__},
  641.  
  642.         {NULL,   (PyCFunction)NULL, 0, NULL}            /* sentinel */
  643. };
  644.  
  645.  
  646. /* Initialization function for the module (*must* be called initpyexpat) */
  647.  
  648. static char pyexpat_module_documentation[] = 
  649. "Python wrapper for Expat parser."
  650. ;
  651.  
  652. void
  653. initpyexpat(){
  654.         PyObject *m, *d;
  655.         char *rev="$Revision: 2.4.2.1 $";
  656.         PyObject *errors_module, *errors_dict;
  657.  
  658.         Xmlparsetype.ob_type = &PyType_Type;
  659.  
  660.         /* Create the module and add the functions */
  661.         m = Py_InitModule4("pyexpat", pyexpat_methods,
  662.                 pyexpat_module_documentation,
  663.                 (PyObject*)NULL,PYTHON_API_VERSION);
  664.  
  665.         /* Add some symbolic constants to the module */
  666.         d = PyModule_GetDict(m);
  667.         ErrorObject = PyString_FromString("pyexpat.error");
  668.         PyDict_SetItemString(d, "error", ErrorObject);
  669.  
  670.         PyDict_SetItemString(d,"__version__",
  671.                              PyString_FromStringAndSize(rev+11,
  672.                                                         strlen(rev+11)-2));
  673.  
  674.         errors_module=PyModule_New( "errors" );
  675.         PyDict_SetItemString(d,"errors", errors_module );
  676.  
  677.         errors_dict=PyModule_GetDict( errors_module );
  678.  
  679. #define MYCONST(name) \
  680.         PyDict_SetItemString(errors_dict, #name,  \
  681.                                 PyString_FromString( XML_ErrorString(name)))
  682.                 
  683.         MYCONST(XML_ERROR_NO_MEMORY);
  684.         MYCONST(XML_ERROR_SYNTAX);
  685.         MYCONST(XML_ERROR_NO_ELEMENTS);
  686.         MYCONST(XML_ERROR_INVALID_TOKEN);
  687.         MYCONST(XML_ERROR_UNCLOSED_TOKEN);
  688.         MYCONST(XML_ERROR_PARTIAL_CHAR);
  689.         MYCONST(XML_ERROR_TAG_MISMATCH);
  690.         MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
  691.         MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
  692.         MYCONST(XML_ERROR_PARAM_ENTITY_REF);
  693.         MYCONST(XML_ERROR_UNDEFINED_ENTITY);
  694.         MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
  695.         MYCONST(XML_ERROR_ASYNC_ENTITY);
  696.         MYCONST(XML_ERROR_BAD_CHAR_REF);
  697.         MYCONST(XML_ERROR_BINARY_ENTITY_REF);
  698.         MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
  699.         MYCONST(XML_ERROR_MISPLACED_XML_PI);
  700.         MYCONST(XML_ERROR_UNKNOWN_ENCODING);
  701.         MYCONST(XML_ERROR_INCORRECT_ENCODING);
  702.         
  703.         /* Check for errors */
  704.         if (PyErr_Occurred())
  705.                 Py_FatalError("can't initialize module pyexpat");
  706. }
  707.  
  708. void clear_handlers( xmlparseobject *self ){
  709.         int i=0;
  710.  
  711.         for( i=0;handler_info[i].name!=NULL;i++ ){
  712.                 self->handlers[i]=NULL;
  713.                 handler_info[i].setter( self->itself, NULL );
  714.         }
  715. }
  716.  
  717. typedef void (*pairsetter)( XML_Parser, void *handler1, void *handler2 );
  718.  
  719. void pyxml_UpdatePairedHandlers( xmlparseobject *self, 
  720.                                 int startHandler, 
  721.                                 int endHandler,
  722.                                 pairsetter setter){
  723.         void *start_handler=NULL;
  724.         void *end_handler=NULL;
  725.  
  726.         if( self->handlers[startHandler] && 
  727.                         self->handlers[endHandler]!=Py_None ){
  728.                 start_handler=handler_info[startHandler].handler;
  729.         }
  730.         if( self->handlers[EndElement] && 
  731.                         self->handlers[EndElement] !=Py_None ){
  732.                 end_handler=handler_info[endHandler].handler;
  733.         }
  734.         
  735.         setter(self->itself, 
  736.                               start_handler,
  737.                               end_handler);
  738. }
  739.  
  740. void pyxml_SetStartElementHandler( XML_Parser *parser, 
  741.                                 void *junk){
  742.         pyxml_UpdatePairedHandlers(
  743.                 (xmlparseobject *)XML_GetUserData( parser ), 
  744.                 StartElement, EndElement,
  745.                 (pairsetter)XML_SetElementHandler);
  746. }
  747.  
  748. void pyxml_SetEndElementHandler( XML_Parser *parser,
  749.                                 void *junk){
  750.         pyxml_UpdatePairedHandlers(
  751.                 (xmlparseobject *)XML_GetUserData( parser ), 
  752.                 StartElement, EndElement,
  753.                 (pairsetter)XML_SetElementHandler);
  754. }
  755.  
  756. void pyxml_SetStartNamespaceDeclHandler( XML_Parser *parser,
  757.                                 void *junk){
  758.         pyxml_UpdatePairedHandlers(
  759.                 (xmlparseobject *)XML_GetUserData( parser ), 
  760.                 StartNamespaceDecl, EndNamespaceDecl,
  761.                 (pairsetter)XML_SetNamespaceDeclHandler);
  762. }
  763.  
  764. void pyxml_SetEndNamespaceDeclHandler( XML_Parser *parser,
  765.                                 void *junk){
  766.         pyxml_UpdatePairedHandlers(
  767.                 (xmlparseobject *)XML_GetUserData( parser ), 
  768.                 StartNamespaceDecl, EndNamespaceDecl, 
  769.                 (pairsetter)XML_SetNamespaceDeclHandler);
  770. }
  771.  
  772. void pyxml_SetStartCdataSection( XML_Parser *parser,
  773.                                 void *junk){
  774.  
  775.         pyxml_UpdatePairedHandlers(
  776.                 (xmlparseobject *)XML_GetUserData( parser ), 
  777.                 StartCdataSection, EndCdataSection, 
  778.                 (pairsetter)XML_SetCdataSectionHandler);
  779. }
  780.  
  781. void pyxml_SetEndCdataSection( XML_Parser *parser,
  782.                                 void *junk){
  783.         pyxml_UpdatePairedHandlers(
  784.                 (xmlparseobject *)XML_GetUserData( parser ), 
  785.                 StartCdataSection, EndCdataSection, 
  786.                 (pairsetter)XML_SetCdataSectionHandler);
  787. }
  788.  
  789. static struct HandlerInfo handler_info[]=
  790. {{"StartElementHandler", 
  791.         pyxml_SetStartElementHandler, 
  792.         my_StartElementHandler},
  793. {"EndElementHandler", 
  794.         pyxml_SetEndElementHandler, 
  795.         my_EndElementHandler},
  796. {"ProcessingInstructionHandler", 
  797.         (xmlhandlersetter)XML_SetProcessingInstructionHandler,
  798.         my_ProcessingInstructionHandler},
  799. {"CharacterDataHandler", 
  800.         (xmlhandlersetter)XML_SetCharacterDataHandler,
  801.         my_CharacterDataHandler},
  802. {"UnparsedEntityDeclHandler", 
  803.         (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
  804.         my_UnparsedEntityDeclHandler },
  805. {"NotationDeclHandler", 
  806.         (xmlhandlersetter)XML_SetNotationDeclHandler,
  807.         my_NotationDeclHandler },
  808. {"StartNamespaceDeclHandler", 
  809.         pyxml_SetStartNamespaceDeclHandler,
  810.         my_StartNamespaceDeclHandler },
  811. {"EndNamespaceDeclHandler", 
  812.         pyxml_SetEndNamespaceDeclHandler,
  813.         my_EndNamespaceDeclHandler },
  814. {"CommentHandler",
  815.         (xmlhandlersetter)XML_SetCommentHandler,
  816.         my_CommentHandler},
  817. {"StartCdataSectionHandler",
  818.         pyxml_SetStartCdataSection,
  819.         my_StartCdataSectionHandler},
  820. {"EndCdataSectionHandler",
  821.         pyxml_SetEndCdataSection,
  822.         my_EndCdataSectionHandler},
  823. {"DefaultHandler",
  824.         (xmlhandlersetter)XML_SetDefaultHandler,
  825.         my_DefaultHandler},
  826. {"DefaultHandlerExpand",
  827.         (xmlhandlersetter)XML_SetDefaultHandlerExpand,
  828.         my_DefaultHandlerExpandHandler},
  829. {"NotStandaloneHandler",
  830.         (xmlhandlersetter)XML_SetNotStandaloneHandler,
  831.         my_NotStandaloneHandler},
  832. {"ExternalEntityRefHandler",
  833.         (xmlhandlersetter)XML_SetExternalEntityRefHandler,
  834.         my_ExternalEntityRefHandler },
  835.  
  836. {NULL, NULL, NULL } /* sentinel */
  837. };
  838.  
  839.  
  840.